home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1995 #5 & #6 / Amiga Plus CD - 1995 - No. 5 and 6.iso / pd / netz / term / extras / source / term-source.lha / termStatusDisplay.c < prev    next >
C/C++ Source or Header  |  1995-06-24  |  31KB  |  1,413 lines

  1. /*
  2. **    termStatusDisplay.c
  3. **
  4. **    Status information display routines
  5. **
  6. **    Copyright © 1990-1995 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12.     /* The information to be displayed. */
  13.  
  14. enum    {    INFO_STATUS,INFO_BUFFER,INFO_PROTOCOL,INFO_EMULATION,INFO_BAUDRATE,
  15.         INFO_PARAMETERS,INFO_CURRENTTIME,INFO_ONLINETIME,INFO_ONLINECOST
  16.     };
  17.  
  18.     /* The current status line display mode. */
  19.  
  20. enum    {    MODE_SCREEN_NORMAL,MODE_SCREEN_COMPRESSED,
  21.         MODE_WB_NORMAL,MODE_WB_COMPRESSED
  22.     };
  23.  
  24.     /* Enumerated text boxes. */
  25.  
  26. enum    {    STATUSBOX_STATUS_FONT,STATUSBOX_PROTOCOL_TERMINAL,
  27.         STATUSBOX_RATE_PARAMETERS,STATUSBOX_TIME_ONLINE
  28.     };
  29.  
  30.     /* The status server passes this structure to the
  31.      * rendering routine if the status information
  32.      * is to be updated.
  33.      */
  34.  
  35. struct ObjectCarrier
  36. {
  37.     struct RastPort     *RPort;
  38.     LONG          FirstColumn,
  39.               FullWidth;
  40.     struct TextBox    **BoxArray,
  41.              *BoxList;
  42. };
  43.  
  44.     /* A custom message type for the display update server. */
  45.  
  46. struct UpdateMessage
  47. {
  48.     struct Message    VanillaMessage;
  49.  
  50.     APTR        Object;
  51.     UBYTE        Mode,
  52.             Type;
  53. };
  54.  
  55.     /* The following static strings are displayed in the status
  56.      * window.
  57.      */
  58.  
  59. STATIC STRPTR    ConfigBufferState[3],
  60.         ConfigEmulation[6],
  61.         ConfigParity[6],
  62.         ConfigStatus[8];
  63.  
  64.     /* Width of the status line text, required in case the user interface
  65.      * font happens to be proportional-spaced.
  66.      */
  67.  
  68. STATIC LONG             StatusLineWidth;
  69.  
  70.     /* The status display update task. */
  71.  
  72. STATIC struct Task        *StatusDisplayTask;
  73. STATIC struct MsgPort        *StatusDisplayPort;
  74.  
  75.     /* Display update data */
  76.  
  77. STATIC BOOL             NeedFullRefresh;
  78. STATIC WORD             UpdateSig;
  79. STATIC ULONG             UpdateMask;
  80.  
  81. STATIC VOID __regargs
  82. DrawSeparator(struct RastPort *RPort)
  83. {
  84.     UWORD    Left    = StatusDisplayLeft,
  85.         Width    = StatusDisplayWidth;
  86.  
  87.     SetAPen(RPort,DrawInfo -> dri_Pens[SHADOWPEN]);
  88.     Move(RPort,Left,StatusDisplayTop);
  89.     Draw(RPort,Left + Width - 1,StatusDisplayTop);
  90.  
  91.     SetAPen(RPort,DrawInfo -> dri_Pens[SHINEPEN]);
  92.     Move(RPort,Left,StatusDisplayTop + 1);
  93.     Draw(RPort,Left + Width - 1,StatusDisplayTop + 1);
  94. }
  95.  
  96.     /* DoStatusInfo(APTR Object,UBYTE Mode,UBYTE Type,STRPTR String):
  97.      *
  98.      *    Display information in the status line area.
  99.      */
  100.  
  101. STATIC VOID __regargs
  102. DoStatusInfo(APTR Object,UBYTE Mode,UBYTE Type,STRPTR String)
  103. {
  104.         /* What mode of operation is the status area in? */
  105.  
  106.     switch(Mode)
  107.     {
  108.             /* Compressed mode. */
  109.  
  110.         case MODE_SCREEN_COMPRESSED:
  111.         {
  112.             struct RastPort *RPort = Object;
  113.  
  114.             STATIC BYTE Offsets[8] =
  115.             {
  116.                  0,
  117.                 -1,    /* Not supported */
  118.                 26,
  119.                 11,
  120.                 40,
  121.                 53,
  122.                 61,
  123.                 72
  124.             };
  125.  
  126.             STATIC UBYTE Strings[8][20];
  127.             UBYTE LineBuffer[90];
  128.             LONG i,j,k,Width;
  129.  
  130.             strcpy(Strings[Type],String);
  131.  
  132.             strcpy(LineBuffer,"         ·              ·             ·            ·       ·          ·         ");
  133.  
  134.             for(i = 0 ; i < 8 ; i++)
  135.             {
  136.                 if(Offsets[i] >= 0)
  137.                 {
  138.                     j = strlen(Strings[i]);
  139.  
  140.                     for(k = 0 ; k < j ; k++)
  141.                         LineBuffer[Offsets[i] + k] = Strings[i][k];
  142.                 }
  143.             }
  144.  
  145.             Width = TextLength(RPort,LineBuffer,80);
  146.  
  147.             if(AttemptLockLayerRom(RPort -> Layer))
  148.             {
  149.                 if((StatusLineWidth && StatusLineWidth != Width) || NeedFullRefresh)
  150.                 {
  151.                     LONG OldPen = ReadAPen(RPort);
  152.  
  153.                     SetAPen(RPort,DrawInfo -> dri_Pens[TEXTPEN]);
  154.                     RectFill(RPort,StatusDisplayLeft,StatusDisplayTop,StatusDisplayLeft + StatusDisplayWidth - 1,StatusDisplayTop + StatusDisplayHeight - 1);
  155.                     SetAPen(RPort,OldPen);
  156.  
  157.                     StatusLineWidth = Width;
  158.                     NeedFullRefresh = FALSE;
  159.                 }
  160.  
  161.                 Move(RPort,StatusDisplayLeft + (StatusDisplayWidth - Width) / 2,StatusDisplayTop + UserFontBase);
  162.                 Text(RPort,LineBuffer,80);
  163.  
  164.                 UnlockLayerRom(RPort -> Layer);
  165.             }
  166.         }
  167.  
  168.         break;
  169.  
  170.             /* Normal mode. */
  171.  
  172.         case MODE_SCREEN_NORMAL:
  173.         {
  174.             STATIC UBYTE Codes[8][2] =
  175.             {
  176.                 STATUSBOX_STATUS_FONT,        0,
  177.                 STATUSBOX_STATUS_FONT,        1,
  178.  
  179.                 STATUSBOX_PROTOCOL_TERMINAL,    0,
  180.                 STATUSBOX_PROTOCOL_TERMINAL,    1,
  181.  
  182.                 STATUSBOX_RATE_PARAMETERS,    0,
  183.                 STATUSBOX_RATE_PARAMETERS,    1,
  184.  
  185.                 STATUSBOX_TIME_ONLINE,        0,
  186.                 STATUSBOX_TIME_ONLINE,        1
  187.             };
  188.  
  189.             struct ObjectCarrier *Carrier = (struct ObjectCarrier *)Object;
  190.  
  191.             if(AttemptLockLayerRom(Carrier -> RPort -> Layer))
  192.             {
  193.                 if(NeedFullRefresh && !Config -> ScreenConfig -> SplitStatus)
  194.                 {
  195.                     struct RastPort    *RPort = Carrier -> RPort;
  196.                     LONG         Left;
  197.  
  198.                     if((Left = StatusDisplayLeft + (StatusDisplayWidth - Carrier -> FullWidth) / 2) < 0)
  199.                         Left = 0;
  200.  
  201.                     Left += Carrier -> FirstColumn - SZ_GetBoxInfo(Carrier -> BoxList,BOX_LEFT);
  202.  
  203.                     SetAPen(RPort,DrawInfo -> dri_Pens[BACKGROUNDPEN]);
  204.                     RectFill(RPort,StatusDisplayLeft,StatusDisplayTop,StatusDisplayLeft + StatusDisplayWidth - 1,StatusDisplayTop + StatusDisplayHeight - 1);
  205.  
  206.                     DrawSeparator(RPort);
  207.  
  208.                     SZ_SetBoxes(Carrier -> BoxList,-1,StatusDisplayTop + 3);
  209.                     SZ_MoveBoxes(Carrier -> BoxList,Left,0);
  210.  
  211.                     SZ_DrawBoxes(RPort,Carrier -> BoxList);
  212.  
  213.                     NeedFullRefresh = FALSE;
  214.                 }
  215.  
  216.                 SZ_PrintLine(Carrier -> RPort,Carrier -> BoxArray[Codes[Type][0]],Codes[Type][1],String);
  217.  
  218.                 UnlockLayerRom(Carrier -> RPort -> Layer);
  219.             }
  220.         }
  221.  
  222.         break;
  223.     }
  224. }
  225.  
  226.     /* DoInfo(APTR Object,UBYTE Mode,UBYTE Type,STRPTR String):
  227.      *
  228.      *    Post an update message to the status display server.
  229.      */
  230.  
  231. STATIC VOID __regargs
  232. DoInfo(APTR Object,UBYTE Mode,UBYTE Type,STRPTR String)
  233. {
  234.     struct UpdateMessage    *Msg;
  235.     WORD             Len = strlen(String) + 1;
  236.  
  237.         /* Allocate enough space to hold both the string
  238.          * and the message.
  239.          */
  240.  
  241.     if(Msg = (struct UpdateMessage *)AllocVecPooled(sizeof(struct UpdateMessage) + Len,MEMF_ANY | MEMF_PUBLIC | MEMF_CLEAR))
  242.     {
  243.             /* Fill in the message head. */
  244.  
  245.         Msg -> VanillaMessage . mn_Length = sizeof(struct UpdateMessage) + Len;
  246.  
  247.             /* Set up the name pointer. */
  248.  
  249.         Msg -> VanillaMessage . mn_Node . ln_Name = (STRPTR)(Msg + 1);
  250.  
  251.             /* Copy the string. */
  252.  
  253.         strcpy(Msg -> VanillaMessage . mn_Node . ln_Name,String);
  254.  
  255.             /* Fill in the remaining data. */
  256.  
  257.         Msg -> Object    = Object;
  258.         Msg -> Mode    = Mode;
  259.         Msg -> Type    = Type;
  260.  
  261.             /* Post the message. */
  262.  
  263.         PutMsg(StatusDisplayPort,(struct Message *)Msg);
  264.     }
  265. }
  266.  
  267.     /* UpdateInfo(APTR Object,UBYTE Mode,UBYTE Type,...):
  268.      *
  269.      *    Update the information displayed in the status
  270.      *    area.
  271.      */
  272.  
  273. STATIC VOID __stdargs
  274. UpdateInfo(APTR Object,UBYTE Mode,UBYTE Type,...)
  275. {
  276.     if(Object)
  277.     {
  278.         UBYTE     MiniBuffer[50];
  279.         STRPTR    *String;
  280.         LONG    *Numeral;
  281.         va_list     VarArgs;
  282.  
  283.         va_start(VarArgs,Type);
  284.  
  285.         String    = (STRPTR *)VarArgs;
  286.         Numeral    = (LONG *)VarArgs;
  287.  
  288.         switch(Type)
  289.         {
  290.             case INFO_STATUS:
  291.  
  292.                 strcpy(MiniBuffer,ConfigStatus[Numeral[0]]);
  293.                 strcat(MiniBuffer,"         ");
  294.  
  295.                 MiniBuffer[9] = 0;
  296.  
  297.                 DoInfo(Object,Mode,Type,MiniBuffer);
  298.  
  299.                 break;
  300.  
  301.             case INFO_BUFFER:
  302.  
  303.                 if(Mode == MODE_SCREEN_NORMAL)
  304.                     DoInfo(Object,Mode,Type,ConfigBufferState[Numeral[0]]);
  305.  
  306.                 break;
  307.  
  308.             case INFO_ONLINECOST:
  309.  
  310.                 strcpy(MiniBuffer,String[0]);
  311.                 strcat(MiniBuffer,"          ");
  312.  
  313.                 MiniBuffer[8] = 0;
  314.  
  315.                 DoInfo(Object,Mode,INFO_ONLINETIME,MiniBuffer);
  316.  
  317.                 break;
  318.  
  319.             case INFO_CURRENTTIME:
  320.  
  321.                 FormatTime(MiniBuffer,Numeral[0],Numeral[1],Numeral[2]);
  322.  
  323.                 DoInfo(Object,Mode,Type,MiniBuffer);
  324.  
  325.                 break;
  326.  
  327.             case INFO_ONLINETIME:
  328.  
  329.                 SPrintf(MiniBuffer,"%02ld:%02ld:%02ld",Numeral[0],Numeral[1],Numeral[2]);
  330.  
  331.                 DoInfo(Object,Mode,Type,MiniBuffer);
  332.  
  333.                 break;
  334.  
  335.             case INFO_BAUDRATE:
  336.  
  337.                 if(LocaleBase)
  338.                     SPrintf(MiniBuffer,"%lD        ",Numeral[0]);
  339.                 else
  340.                     SPrintf(MiniBuffer,"%ld        ",Numeral[0]);
  341.  
  342.                 MiniBuffer[7] = 0;
  343.  
  344.                 DoInfo(Object,Mode,Type,MiniBuffer);
  345.  
  346.                 break;
  347.  
  348.             case INFO_PROTOCOL:
  349.             case INFO_EMULATION:
  350.  
  351.                 strcpy(MiniBuffer,String[0]);
  352.  
  353.                 strcat(MiniBuffer,"           ");
  354.  
  355.                 MiniBuffer[12] = 0;
  356.  
  357.                 DoInfo(Object,Mode,Type,MiniBuffer);
  358.  
  359.                 break;
  360.  
  361.             case INFO_PARAMETERS:
  362.  
  363.                 if(Mode == MODE_SCREEN_COMPRESSED)
  364.                 {
  365.                     STATIC UBYTE Parities[5] =
  366.                     {
  367.                         'N','E','O','M','S'
  368.                     };
  369.  
  370.                     SPrintf(MiniBuffer,"%ld-%lc-%ld",Numeral[0],Parities[Numeral[1]],Numeral[2]);
  371.                 }
  372.                 else
  373.                     SPrintf(MiniBuffer,"%ld-%s-%ld",Numeral[0],ConfigParity[Numeral[1]],Numeral[2]);
  374.  
  375.                 DoInfo(Object,Mode,Type,MiniBuffer);
  376.  
  377.                 break;
  378.         }
  379.  
  380.         va_end(VarArgs);
  381.     }
  382. }
  383.  
  384.     /* Raise(UWORD Colour):
  385.      *
  386.      *    Make an RGB value brighter.
  387.      */
  388.  
  389. STATIC UWORD __inline
  390. Raise(UWORD Colour)
  391. {
  392.     UWORD R,G,B;
  393.  
  394.     R =  (Colour >> 8)        + 4;
  395.     G = ((Colour >> 4) & 0xF) + 4;
  396.     B = ((Colour     ) & 0xF) + 4;
  397.  
  398.     if(R > 15)
  399.         R = 15;
  400.  
  401.     if(G > 15)
  402.         G = 15;
  403.  
  404.     if(B > 15)
  405.         B = 15;
  406.  
  407.     return((UWORD)(R << 8 | G << 4 | B));
  408. }
  409.  
  410.     /* VisualBeep():
  411.      *
  412.      *    Handle the visual part of the display beep.
  413.      */
  414.  
  415. STATIC BYTE
  416. VisualBeep(VOID)
  417. {
  418.     struct UCopList    *UserCopperList;
  419.  
  420.         /* Create a user copper list. */
  421.  
  422.     if(UserCopperList = (struct UCopList *)AllocMem(sizeof(struct UCopList),MEMF_ANY|MEMF_CLEAR))
  423.     {
  424.             /* Initialize for 35 commands. */
  425.  
  426.         if(UCopperListInit(UserCopperList,1 + 16 + 1 + 16 + 1))
  427.         {
  428.             WORD i;
  429.  
  430.                 /* Wait until first line of window. */
  431.  
  432.             CWAIT(UserCopperList,Window -> TopEdge,0);
  433.  
  434.                 /* Set the light colours. */
  435.  
  436.             for(i = 0 ; i < 16 ; i++)
  437.                 CMOVE(UserCopperList,custom . color[i],Raise(GetRGB4(Screen -> ViewPort . ColorMap,i)));
  438.  
  439.                 /* Wait until bottom of window. */
  440.  
  441.             CWAIT(UserCopperList,Window -> TopEdge + Window -> Height - 1,0);
  442.  
  443.                 /* Set the standard colours. */
  444.  
  445.             for(i = 0 ; i < 16 ; i++)
  446.                 CMOVE(UserCopperList,custom . color[i],GetRGB4(Screen -> ViewPort . ColorMap,i));
  447.  
  448.                 /* Finish list. */
  449.  
  450.             CEND(UserCopperList);
  451.  
  452.                 /* Install user copper list... */
  453.  
  454.             Screen -> ViewPort . UCopIns = UserCopperList;
  455.  
  456.                 /* ...and display it. */
  457.  
  458.             RethinkDisplay();
  459.  
  460.             return(TRUE);
  461.         }
  462.         else
  463.             FreeMem(UserCopperList,sizeof(struct UCopList));
  464.     }
  465.  
  466.     return(FALSE);
  467. }
  468.  
  469.     /* StatusDisplayServer(VOID):
  470.      *
  471.      *    Yet another asynchronous background task to display
  472.      *    some information.
  473.      */
  474.  
  475. STATIC VOID __saveds
  476. StatusDisplayServer(VOID)
  477. {
  478.         /* Create the interface port. */
  479.  
  480.     if(StatusDisplayPort = CreateMsgPort())
  481.     {
  482.         struct UpdateMessage    *Msg;
  483.         ULONG             Signals;
  484.  
  485.             /* Ring back... */
  486.  
  487.         Signal(StatusProcess,SIG_HANDSHAKE);
  488.  
  489.             /* Wait for messages or termination signal. */
  490.  
  491.         FOREVER
  492.         {
  493.             Signals = Wait(SIG_KILL | PORTMASK(StatusDisplayPort));
  494.  
  495.                 /* Termination? */
  496.  
  497.             if(Signals & SIG_KILL)
  498.                 break;
  499.  
  500.                 /* Message arrival? */
  501.  
  502.             if(Signals & PORTMASK(StatusDisplayPort))
  503.             {
  504.                     /* Process all pending messages. */
  505.  
  506.                 while(Msg = (struct UpdateMessage *)GetMsg(StatusDisplayPort))
  507.                 {
  508.                     DoStatusInfo(Msg -> Object,Msg -> Mode,Msg -> Type,Msg -> VanillaMessage . mn_Node . ln_Name);
  509.  
  510.                     FreeVecPooled(Msg);
  511.                 }
  512.             }
  513.         }
  514.  
  515.             /* Remove all pending messages. */
  516.  
  517.         while(Msg = (struct UpdateMessage *)GetMsg(StatusDisplayPort))
  518.             FreeVecPooled(Msg);
  519.  
  520.             /* Remove the msgport. */
  521.  
  522.         DeleteMsgPort(StatusDisplayPort);
  523.     }
  524.  
  525.         /* Lock & quit... */
  526.  
  527.     Forbid();
  528.  
  529.     Signal(StatusProcess,SIG_HANDSHAKE);
  530.  
  531.     RemTask(StatusDisplayTask = NULL);
  532. }
  533.  
  534.     /* StatusServer():
  535.      *
  536.      *    Asynchronous process to continuosly display the current
  537.      *    terminal settings.
  538.      */
  539.  
  540. VOID __saveds
  541. StatusServer()
  542. {
  543.     STATIC struct timeval     OnlineTime,
  544.                  LastTime,
  545.                  TempTime;
  546.     STATIC BYTE         GotOnline        = FALSE,
  547.                  WasOnline        = FALSE,
  548.                  ShowPay        = FALSE,
  549.                  FlagBit        = FALSE;
  550.     STATIC LONG         SecCount        = 0,
  551.                  MinCount        = 0,
  552.                  BeepCount        = 0;
  553.  
  554.     struct TextBox        *BoxArray[4],
  555.                 *BoxList = NULL,
  556.                 *Box;
  557.  
  558.     struct RastPort        *RPort;
  559.  
  560.     APTR             SomeObject;
  561.     struct ObjectCarrier     Carrier;
  562.  
  563.     struct timerequest    *StatusTimeRequest;
  564.     struct MsgPort        *StatusTimePort;
  565.  
  566.     BYTE             Background        = FALSE,
  567.                  FlashIt        = FALSE,
  568.                  SetColours        = FALSE,
  569.                  StandardColours    = TRUE,
  570.                  KeepGoing        = TRUE,
  571.                  Beeping        = FALSE,
  572.                  StatusMode        = Config -> ScreenConfig -> StatusLine;
  573.  
  574.     BYTE             LastProtocol[40],
  575.                  LastEmulationName[40];
  576.  
  577.     BYTE             LastFrozen        = -1,
  578.                  LastEmulation        = -1,
  579.                  LastBitsPerChar    = -1,
  580.                  LastParity        = -1,
  581.                  LastStopBits        = -1,
  582.                  LastStatus        = -1;
  583.  
  584.     LONG             LastBaud        = -1;
  585.  
  586.     LONG             i,
  587.                  ThisHour,
  588.                  ThisMinute,
  589.                  BoxCounter = 0,
  590.                  FullWidth;
  591.     WORD             ColumnLeft[4],
  592.                  ColumnWidth[4],
  593.                  Max,
  594.                  Len;
  595.  
  596.     BYTE             AllFine = TRUE;
  597.     UBYTE             Mode;
  598.  
  599.     StatusLineWidth = 0;
  600.  
  601.     LastProtocol[0] = 0;
  602.  
  603.     LastEmulationName[0] = 0;
  604.  
  605.     LocalizeString(ConfigBufferState,MSG_TERMSTATUSDISPLAY_FROZEN_TXT,MSG_TERMSTATUSDISPLAY_RECORDING_TXT);
  606.     LocalizeString(ConfigEmulation,MSG_TERMAUX_ANSI_VT102_TXT,MSG_TERMAUX_HEX_TXT);
  607.     LocalizeString(ConfigParity,MSG_TERMAUX_NONE_TXT,MSG_TERMAUX_SPACE_TXT);
  608.     LocalizeString(ConfigStatus,MSG_TERMAUX_READY_TXT,MSG_TERMAUX_RECORD_LINE_TXT);
  609.  
  610.     if(StatusWindow)
  611.         RPort = StatusWindow -> RPort;
  612.     else
  613.         RPort = StatusRPort;
  614.  
  615.     if(RPort)
  616.     {
  617.         SetAPen(RPort,DrawInfo -> dri_Pens[BACKGROUNDPEN]);
  618.         RectFill(RPort,StatusDisplayLeft,StatusDisplayTop,StatusDisplayLeft + StatusDisplayWidth - 1,StatusDisplayTop + StatusDisplayHeight - 1);
  619.  
  620.             /* Render the information. */
  621.  
  622.         if(StatusWindow)
  623.             SZ_SizeSetup(StatusWindow -> WScreen,&UserFont);
  624.         else
  625.             SZ_SizeSetup(Window -> WScreen,&UserFont);
  626.  
  627.         if(StatusMode == STATUSLINE_COMPRESSED)
  628.         {
  629.             StatusOffset = (StatusDisplayWidth - 80 * UserFontWidth) / 2;
  630.  
  631.             SetAPen(RPort,DrawInfo -> dri_Pens[TEXTPEN]);
  632.             RectFill(RPort,StatusDisplayLeft,StatusDisplayTop,StatusDisplayLeft + StatusDisplayWidth - 1,StatusDisplayTop + StatusDisplayHeight - 1);
  633.  
  634.             SetDrMd(RPort,JAM2);
  635.             SetAPen(RPort,DrawInfo -> dri_Pens[BACKGROUNDPEN]);
  636.             SetBPen(RPort,DrawInfo -> dri_Pens[TEXTPEN]);
  637.  
  638.             SetFont(RPort,UserTextFont);
  639.         }
  640.         else
  641.         {
  642.             SetBPen(RPort,DrawInfo -> dri_Pens[BACKGROUNDPEN]);
  643.  
  644.                 /* Draw a separating line. */
  645.  
  646.             if(!Config -> ScreenConfig -> SplitStatus)
  647.                 DrawSeparator(RPort);
  648.  
  649.             SetAPen(RPort,DrawInfo -> dri_Pens[TEXTPEN]);
  650.  
  651.             ColumnLeft[0] = SZ_LeftOffsetN(MSG_TERMSTATUSDISPLAY_STATUS_TXT,MSG_TERMSTATUSDISPLAY_FONT_TXT,-1);
  652.             ColumnLeft[1] = SZ_LeftOffsetN(MSG_TERMSTATUSDISPLAY_PROTOCOL_TXT,MSG_TERMSTATUSDISPLAY_TERMINAL_TXT,-1);
  653.             ColumnLeft[2] = SZ_LeftOffsetN(MSG_TERMSTATUSDISPLAY_BAUDRATE_TXT,MSG_TERMSTATUSDISPLAY_PARAMETERS_TXT,-1);
  654.             ColumnLeft[3] = SZ_LeftOffsetN(MSG_TERMSTATUSDISPLAY_TIME_TXT,MSG_TERMSTATUSDISPLAY_ONLINE_TXT,-1);
  655.  
  656.             Max = 0;
  657.  
  658.             for(i = 0 ; ConfigStatus[i] ; i++)
  659.             {
  660.                 if((Len = SZ_BoxWidth(strlen(ConfigStatus[i]))) > Max)
  661.                     Max = Len;
  662.             }
  663.  
  664.             for(i = 0 ; ConfigBufferState[i] ; i++)
  665.             {
  666.                 if((Len = SZ_BoxWidth(strlen(ConfigBufferState[i]))) > Max)
  667.                     Max = Len;
  668.             }
  669.  
  670.             ColumnWidth[0] = Max;
  671.  
  672.             Max = SZ_BoxWidth(12);
  673.  
  674.             for(i = 0 ; ConfigEmulation[i] ; i++)
  675.             {
  676.                 if((Len = SZ_BoxWidth(strlen(ConfigEmulation[i]))) > Max)
  677.                     Max = Len;
  678.             }
  679.  
  680.             ColumnWidth[1] = Max;
  681.  
  682.             Max = SZ_BoxWidth(10);
  683.  
  684.             for(i = 0 ; ConfigParity[i] ; i++)
  685.             {
  686.                 if((Len = SZ_BoxWidth(4 + strlen(ConfigParity[i]))) > Max)
  687.                     Max = Len;
  688.             }
  689.  
  690.             ColumnWidth[2] = Max;
  691.  
  692.             ColumnWidth[3] = SZ_BoxWidth(8);
  693.  
  694.             FullWidth = 0;
  695.  
  696.             for(i = 0 ; i < 4 ; i++)
  697.                 FullWidth += ColumnWidth[i] + ColumnLeft[i];
  698.  
  699.             FullWidth += 3 * InterWidth + 2;
  700.  
  701.             Carrier . FullWidth    = FullWidth;
  702.             Carrier . FirstColumn    = ColumnLeft[0];
  703.  
  704.             if(!Config -> ScreenConfig -> SplitStatus)
  705.             {
  706.                 if(FullWidth > StatusDisplayWidth)
  707.                     SZ_SetLeftEdge(StatusDisplayLeft + ColumnLeft[0]);
  708.                 else
  709.                     SZ_SetLeftEdge(StatusDisplayLeft + (StatusDisplayWidth - FullWidth) / 2 + ColumnLeft[0]);
  710.  
  711.                 SZ_SetAbsoluteTop(StatusDisplayTop + 3);
  712.                 SZ_SetTopEdge(StatusDisplayTop + 3);
  713.             }
  714.             else
  715.             {
  716.                 SZ_SetLeftEdge(StatusDisplayLeft + ColumnLeft[0] + 1);
  717.  
  718.                 SZ_SetAbsoluteTop(StatusDisplayTop + 1);
  719.                 SZ_SetTopEdge(StatusDisplayTop + 1);
  720.             }
  721.  
  722.             SZ_SetWidth(ColumnWidth[0]);
  723.  
  724.             BoxArray[BoxCounter++] = Box = SZ_CreateTextBox(&BoxList,
  725.                 SZ_Lines,    2,
  726.                 SZ_AutoWidth,    TRUE,
  727.             TAG_DONE);
  728.  
  729.             SZ_SetBoxTitles(Box,LocaleString(MSG_TERMSTATUSDISPLAY_STATUS_TXT),LocaleString(MSG_TERMSTATUSDISPLAY_FONT_TXT),NULL);
  730.  
  731.             SZ_SetWidth(ColumnWidth[1]);
  732.             SZ_AddLeftOffset(ColumnLeft[1]);
  733.  
  734.             BoxArray[BoxCounter++] = Box = SZ_CreateTextBox(&BoxList,
  735.                 SZ_Lines,    2,
  736.                 SZ_AutoWidth,    TRUE,
  737.                 SZ_NewColumn,    TRUE,
  738.             TAG_DONE);
  739.  
  740.             SZ_SetBoxTitles(Box,LocaleString(MSG_TERMSTATUSDISPLAY_PROTOCOL_TXT),LocaleString(MSG_TERMSTATUSDISPLAY_TERMINAL_TXT),NULL);
  741.  
  742.             SZ_SetWidth(ColumnWidth[2]);
  743.             SZ_AddLeftOffset(ColumnLeft[2]);
  744.  
  745.             BoxArray[BoxCounter++] = Box = SZ_CreateTextBox(&BoxList,
  746.                 SZ_Lines,    2,
  747.                 SZ_AutoWidth,    TRUE,
  748.                 SZ_NewColumn,    TRUE,
  749.             TAG_DONE);
  750.  
  751.             SZ_SetBoxTitles(Box,LocaleString(MSG_TERMSTATUSDISPLAY_BAUDRATE_TXT),LocaleString(MSG_TERMSTATUSDISPLAY_PARAMETERS_TXT),NULL);
  752.  
  753.             SZ_SetWidth(ColumnWidth[3]);
  754.             SZ_AddLeftOffset(ColumnLeft[3]);
  755.  
  756.             BoxArray[BoxCounter] = Box = SZ_CreateTextBox(&BoxList,
  757.                 SZ_Lines,    2,
  758.                 SZ_AutoWidth,    TRUE,
  759.                 SZ_NewColumn,    TRUE,
  760.             TAG_DONE);
  761.  
  762.             SZ_SetBoxTitles(Box,LocaleString(MSG_TERMSTATUSDISPLAY_TIME_TXT),LocaleString(MSG_TERMSTATUSDISPLAY_ONLINE_TXT),NULL);
  763.  
  764.             if(!Box)
  765.                 AllFine = FALSE;
  766.             else
  767.                 SZ_DrawBoxes(RPort,BoxList);
  768.         }
  769.     }
  770.     else
  771.         AllFine = TRUE;
  772.  
  773.     if((UpdateSig = AllocSignal(-1)) == -1)
  774.         AllFine = FALSE;
  775.     else
  776.         UpdateMask = 1L << UpdateSig;
  777.  
  778.         /* Everything fine so far? */
  779.  
  780.     if(AllFine)
  781.     {
  782.         Forbid();
  783.  
  784.             /* Create the display server task. */
  785.  
  786.         if(StatusDisplayTask = CreateTask("term Status Display Task",5,StatusDisplayServer,4000))
  787.         {
  788.             ClrSignal(SIG_HANDSHAKE);
  789.  
  790.             Wait(SIG_HANDSHAKE);
  791.         }
  792.  
  793.         Permit();
  794.     }
  795.  
  796.         /* Is the display server task up and running? */
  797.  
  798.     if(StatusDisplayTask)
  799.     {
  800.             /* Create a timer device request. */
  801.  
  802.         if(StatusTimePort = (struct MsgPort *)CreateMsgPort())
  803.         {
  804.             if(StatusTimeRequest = (struct timerequest *)CreateIORequest(StatusTimePort,sizeof(struct timerequest)))
  805.             {
  806.                 if(!OpenDevice(TIMERNAME,UNIT_VBLANK,StatusTimeRequest,0))
  807.                 {
  808.                         /* Signal our father process
  809.                          * that we're running.
  810.                          */
  811.  
  812.                     Signal(ThisProcess,SIG_HANDSHAKE);
  813.  
  814.                     if(RPort)
  815.                     {
  816.                         if(StatusMode == STATUSLINE_COMPRESSED)
  817.                         {
  818.                             Mode = MODE_SCREEN_COMPRESSED;
  819.  
  820.                             SomeObject = RPort;
  821.                         }
  822.                         else
  823.                         {
  824.                             Mode = MODE_SCREEN_NORMAL;
  825.  
  826.                             Carrier . RPort        = RPort;
  827.                             Carrier . BoxArray    = BoxArray;
  828.                             Carrier . BoxList    = BoxList;
  829.  
  830.                             SomeObject = &Carrier;
  831.                         }
  832.  
  833.                         UpdateInfo(SomeObject,Mode,INFO_ONLINETIME,0,0,0);
  834.                     }
  835.  
  836.                         /* Keep on displaying. */
  837.  
  838.                     while(KeepGoing)
  839.                     {
  840.                             /* Are we to quit? */
  841.  
  842.                         if(CheckSignal(SIG_KILL))
  843.                             KeepGoing = FALSE;
  844.  
  845.                             /* Get the current time. */
  846.  
  847.                         StatusTimeRequest -> tr_node . io_Command = TR_GETSYSTIME;
  848.  
  849.                         DoIO(StatusTimeRequest);
  850.  
  851.                             /* A connection has just
  852.                              * been established.
  853.                              */
  854.  
  855.                         ObtainSemaphore(&OnlineSemaphore);
  856.  
  857.                         if(Online && !GotOnline)
  858.                         {
  859.                             OnlineTime = StatusTimeRequest -> tr_time;
  860.  
  861.                                 /* Add up connection time. */
  862.  
  863.                             if(OnlinePlus)
  864.                             {
  865.                                 struct timeval GetBack;
  866.  
  867.                                 GetBack . tv_secs    = OnlinePlus;
  868.                                 GetBack . tv_micro    = 0;
  869.  
  870.                                     /* Technically, the connection happened a
  871.                                      * bit earlier.
  872.                                      */
  873.  
  874.                                 SubTime(&OnlineTime,&GetBack);
  875.  
  876.                                     /* Choose the right rate accounting
  877.                                      * time.
  878.                                      */
  879.  
  880.                                 SelectTime(ChosenEntry,ChosenPattern,&OnlineTime);
  881.  
  882.                                     /* Enter the first rate. */
  883.  
  884.                                 if(!CurrentPay)
  885.                                     CurrentPay = PayPerUnit[DT_FIRST_UNIT];
  886.  
  887.                                     /* Take care of the remaining seconds. */
  888.  
  889.                                 while(SecPerUnit[WhichUnit] && OnlinePlus >= SecPerUnit[WhichUnit])
  890.                                 {
  891.                                     WhichUnit = DT_NEXT_UNIT;
  892.  
  893.                                     CurrentPay += PayPerUnit[DT_NEXT_UNIT];
  894.  
  895.                                     OnlinePlus -= SecPerUnit[WhichUnit];
  896.                                 }
  897.  
  898.                                     /* Remember the remaining seconds. */
  899.  
  900.                                 SecCount = OnlinePlus;
  901.  
  902.                                 OnlinePlus = 0;
  903.                             }
  904.                             else
  905.                                 SecCount = 0;
  906.  
  907.                             GotOnline    = TRUE;
  908.                             FlagBit        = FALSE;
  909.                         }
  910.  
  911.                         ReleaseSemaphore(&OnlineSemaphore);
  912.  
  913.                             /* Print the current time. */
  914.  
  915.                         ThisHour    = (StatusTimeRequest -> tr_time . tv_secs % 86400) / 3600;
  916.                         ThisMinute    = (StatusTimeRequest -> tr_time . tv_secs % 3600) / 60;
  917.  
  918.                         UpdateInfo(SomeObject,Mode,INFO_CURRENTTIME,ThisHour,ThisMinute,StatusTimeRequest -> tr_time . tv_secs % 60);
  919.  
  920.                             /* Handle routine checkup actions. */
  921.  
  922.                         if(!(SecCount & 1))
  923.                             Signal(ThisProcess,SIG_CHECK);
  924.  
  925.                         ObtainSemaphore(&OnlineSemaphore);
  926.  
  927.                         if(Online)
  928.                         {
  929.                             ReleaseSemaphore(&OnlineSemaphore);
  930.  
  931.                             WasOnline = TRUE;
  932.  
  933.                             ObtainSemaphore(&PatternSemaphore);
  934.  
  935.                             if(ChosenEntry || ChosenPattern)
  936.                             {
  937.                                 if(!(StatusTimeRequest -> tr_time . tv_secs % 60))
  938.                                     SelectTime(ChosenEntry,ChosenPattern,NULL);
  939.  
  940.                                 if(!CurrentPay)
  941.                                     CurrentPay = PayPerUnit[DT_FIRST_UNIT];
  942.  
  943.                                 FlagBit ^= TRUE;
  944.  
  945.                                 if(!FlagBit)
  946.                                 {
  947.                                     while(SecPerUnit[WhichUnit] && SecCount >= SecPerUnit[WhichUnit])
  948.                                     {
  949.                                         SecCount -= SecPerUnit[WhichUnit];
  950.  
  951.                                         WhichUnit = DT_NEXT_UNIT;
  952.  
  953.                                         CurrentPay += PayPerUnit[DT_NEXT_UNIT];
  954.                                     }
  955.  
  956.                                     SecCount++;
  957.                                 }
  958.                             }
  959.  
  960.                             ReleaseSemaphore(&PatternSemaphore);
  961.  
  962.                                 /* Show the time
  963.                                  * we have been online
  964.                                  * yet.
  965.                                  */
  966.  
  967.                             TempTime = StatusTimeRequest -> tr_time;
  968.  
  969.                             SubTime(&TempTime,&OnlineTime);
  970.  
  971.                             if(StatusTimeRequest -> tr_time . tv_secs != LastTime . tv_secs)
  972.                             {
  973.                                 LastTime = StatusTimeRequest -> tr_time;
  974.  
  975.                                 switch(Config -> ScreenConfig -> TimeMode)
  976.                                 {
  977.                                     case ONLINETIME_TIME:    ShowPay = FALSE;
  978.                                                 break;
  979.  
  980.                                     case ONLINETIME_COST:    ShowPay = TRUE;
  981.                                                 break;
  982.  
  983.                                     case ONLINETIME_BOTH:    if(TempTime . tv_secs && !(TempTime . tv_secs % 5))
  984.                                                     ShowPay ^= TRUE;
  985.  
  986.                                                 break;
  987.                                 }
  988.  
  989.                                 ObtainSemaphore(&PatternSemaphore);
  990.  
  991.                                 if(ShowPay && (ChosenEntry || ChosenPattern))
  992.                                     UpdateInfo(SomeObject,Mode,INFO_ONLINECOST,CreateSum(CurrentPay,FALSE));
  993.                                 else
  994.                                     UpdateInfo(SomeObject,Mode,INFO_ONLINETIME,(TempTime . tv_secs % 86400) / 3600,(TempTime . tv_secs % 3600) / 60,TempTime . tv_secs % 60);
  995.  
  996.                                 ReleaseSemaphore(&PatternSemaphore);
  997.  
  998.                                 OnlineMinutes = TempTime . tv_secs / 60;
  999.                             }
  1000.                         }
  1001.                         else
  1002.                         {
  1003.                             ReleaseSemaphore(&OnlineSemaphore);
  1004.  
  1005.                             if(WasOnline)
  1006.                             {
  1007.                                 WasOnline = FALSE;
  1008.  
  1009.                                 UpdateInfo(SomeObject,Mode,INFO_ONLINETIME,(TempTime . tv_secs % 86400) / 3600,(TempTime . tv_secs % 3600) / 60,TempTime . tv_secs % 60);
  1010.                             }
  1011.  
  1012.                             if(GotOnline)
  1013.                                 GotOnline = FALSE;
  1014.                         }
  1015.  
  1016.                             /* Take care of the visual beep
  1017.                              * if enabled.
  1018.                              */
  1019.  
  1020.                         if(Beeping)
  1021.                         {
  1022.                             if(!(BeepCount--))
  1023.                             {
  1024.                                 Beeping = FALSE;
  1025.  
  1026.                                     /* Remove the copper list. */
  1027.  
  1028.                                 FreeVPortCopLists(&Screen -> ViewPort);
  1029.  
  1030.                                     /* Really remove it. */
  1031.  
  1032.                                 RemakeDisplay();
  1033.  
  1034.                                     /* Clear the signal bit. */
  1035.  
  1036.                                 ClrSignal(SIG_BELL);
  1037.                             }
  1038.                         }
  1039.  
  1040.                             /* Are we to show a visual beep? */
  1041.  
  1042.                         if(CheckSignal(SIG_BELL))
  1043.                         {
  1044.                             if(Config -> TerminalConfig -> BellMode == BELL_SYSTEM)
  1045.                                 DisplayBeep(Window -> WScreen);
  1046.                             else
  1047.                             {
  1048.                                 if(Screen && !Config -> ScreenConfig -> UseWorkbench && !Beeping && (Config -> TerminalConfig -> BellMode == BELL_VISIBLE || Config -> TerminalConfig -> BellMode == BELL_BOTH))
  1049.                                 {
  1050.                                     if(VisualBeep())
  1051.                                     {
  1052.                                         Beeping = TRUE;
  1053.  
  1054.                                         BeepCount = 1;
  1055.                                     }
  1056.                                 }
  1057.                             }
  1058.                         }
  1059.  
  1060.                             /* Display the current terminal
  1061.                              * status.
  1062.                              */
  1063.  
  1064.                         if(LastStatus != Status)
  1065.                             UpdateInfo(SomeObject,Mode,INFO_STATUS,LastStatus = Status);
  1066.  
  1067.                             /* Show the current transfer
  1068.                              * protocol.
  1069.                              */
  1070.  
  1071.                         if(strcmp(LastProtocol,TransferProtocolName))
  1072.                         {
  1073.                             strcpy(LastProtocol,TransferProtocolName);
  1074.  
  1075.                             if(LastProtocol[0])
  1076.                                 UpdateInfo(SomeObject,Mode,INFO_PROTOCOL,LastProtocol);
  1077.                             else
  1078.                                 UpdateInfo(SomeObject,Mode,INFO_PROTOCOL,"-");
  1079.                         }
  1080.  
  1081.                             /* Show the current baud
  1082.                              * rate.
  1083.                              */
  1084.  
  1085.                         if(LastBaud != Config -> SerialConfig -> BaudRate)
  1086.                             UpdateInfo(SomeObject,Mode,INFO_BAUDRATE,LastBaud = Config -> SerialConfig -> BaudRate);
  1087.  
  1088.                             /* Show the current
  1089.                              * terminal font.
  1090.                              */
  1091.  
  1092.                         if(LastFrozen != BufferFrozen)
  1093.                         {
  1094.                             LastFrozen = BufferFrozen;
  1095.  
  1096.                             UpdateInfo(SomeObject,Mode,INFO_BUFFER,LastFrozen != TRUE);
  1097.                         }
  1098.  
  1099.                             /* Show the current terminal
  1100.                              * emulation.
  1101.                              */
  1102.  
  1103.                         if(LastEmulation != Config -> TerminalConfig -> EmulationMode || (Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL && Stricmp(EmulationName,LastEmulationName)))
  1104.                         {
  1105.                             LastEmulation = Config -> TerminalConfig -> EmulationMode;
  1106.  
  1107.                             if(Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  1108.                             {
  1109.                                 UpdateInfo(SomeObject,Mode,INFO_EMULATION,EmulationName);
  1110.  
  1111.                                 strcpy(LastEmulationName,EmulationName);
  1112.                             }
  1113.                             else
  1114.                                 UpdateInfo(SomeObject,Mode,INFO_EMULATION,ConfigEmulation[LastEmulation]);
  1115.                         }
  1116.  
  1117.                             /* Show the current serial
  1118.                              * parameters (parity, etc).
  1119.                              */
  1120.  
  1121.                         if(LastBitsPerChar != Config -> SerialConfig -> BitsPerChar || LastParity != Config -> SerialConfig -> Parity || LastStopBits != Config -> SerialConfig -> StopBits)
  1122.                         {
  1123.                             LastBitsPerChar    = Config -> SerialConfig -> BitsPerChar;
  1124.                             LastParity    = Config -> SerialConfig -> Parity;
  1125.                             LastStopBits    = Config -> SerialConfig -> StopBits;
  1126.  
  1127.                             UpdateInfo(SomeObject,Mode,INFO_PARAMETERS,LastBitsPerChar,LastParity,LastStopBits);
  1128.                         }
  1129.  
  1130.                             /* Wait another half a second. */
  1131.  
  1132.                         if(KeepGoing)
  1133.                         {
  1134.                             ULONG    Mask;
  1135.                             BOOLEAN    ResetTime = FALSE;
  1136.  
  1137.                             StatusTimeRequest -> tr_node . io_Command    = TR_ADDREQUEST;
  1138.                             StatusTimeRequest -> tr_time . tv_secs        = 0;
  1139.                             StatusTimeRequest -> tr_time . tv_micro        = MILLION / 2;
  1140.  
  1141.                             SendIO(StatusTimeRequest);
  1142.  
  1143.                             FOREVER
  1144.                             {
  1145.                                 Mask = Wait(SIG_BELL | PORTMASK(StatusTimePort) | SIG_CLOSEWINDOW | SIG_RESETTIME | UpdateMask);
  1146.  
  1147.                                 if(Mask & UpdateMask)
  1148.                                 {
  1149.                                     Signal(ThisProcess,SIG_HANDSHAKE);
  1150.  
  1151.                                     Wait(UpdateMask);
  1152.  
  1153.                                     NeedFullRefresh = TRUE;
  1154.  
  1155.                                     UpdateInfo(SomeObject,Mode,INFO_STATUS,LastStatus = Status);
  1156.                                 }
  1157.  
  1158.                                     /* Close the window and keep quiet? */
  1159.  
  1160.                                 if(Mask & SIG_CLOSEWINDOW)
  1161.                                 {
  1162.                                     Forbid();
  1163.  
  1164.                                     if(StatusDisplayTask)
  1165.                                     {
  1166.                                         Signal(StatusDisplayTask,SIG_KILL);
  1167.  
  1168.                                         ClrSignal(SIG_HANDSHAKE);
  1169.  
  1170.                                         Wait(SIG_HANDSHAKE);
  1171.                                     }
  1172.  
  1173.                                     if(BoxList)
  1174.                                     {
  1175.                                         SZ_FreeBoxes(BoxList);
  1176.  
  1177.                                         BoxList = NULL;
  1178.                                     }
  1179.  
  1180.                                     SomeObject = NULL;
  1181.  
  1182.                                     Signal(ThisProcess,SIG_HANDSHAKE);
  1183.  
  1184.                                     Config -> ScreenConfig -> StatusLine = STATUSLINE_DISABLED;
  1185.  
  1186.                                     Permit();
  1187.                                 }
  1188.  
  1189.                                 if(Mask & SIG_BELL)
  1190.                                 {
  1191.                                     if(Config -> TerminalConfig -> BellMode == BELL_SYSTEM)
  1192.                                         DisplayBeep(Window -> WScreen);
  1193.                                     else
  1194.                                     {
  1195.                                         if(Screen && !Config -> ScreenConfig -> UseWorkbench && !Beeping && (Config -> TerminalConfig -> BellMode == BELL_VISIBLE || Config -> TerminalConfig -> BellMode == BELL_BOTH))
  1196.                                         {
  1197.                                             if(VisualBeep())
  1198.                                             {
  1199.                                                 Beeping = TRUE;
  1200.  
  1201.                                                 BeepCount = 1;
  1202.                                             }
  1203.                                         }
  1204.                                     }
  1205.                                 }
  1206.  
  1207.                                     /* Reset the online time counter. */
  1208.  
  1209.                                 if(Mask & SIG_RESETTIME)
  1210.                                     ResetTime = TRUE;
  1211.  
  1212.                                 if(Mask & PORTMASK(StatusTimePort))
  1213.                                 {
  1214.                                     WaitIO(StatusTimeRequest);
  1215.  
  1216.                                     break;
  1217.                                 }
  1218.                             }
  1219.  
  1220.                                 /* Reset the online time. */
  1221.  
  1222.                             if(ResetTime)
  1223.                             {
  1224.                                 StatusTimeRequest -> tr_node . io_Command = TR_GETSYSTIME;
  1225.  
  1226.                                 DoIO(StatusTimeRequest);
  1227.  
  1228.                                 OnlineTime = StatusTimeRequest -> tr_time;
  1229.                             }
  1230.  
  1231.                                 /* Count up to a minute. */
  1232.  
  1233.                             if(MinCount++ == 120)
  1234.                             {
  1235.                                 MinCount = 0;
  1236.  
  1237.                                     /* Time limit present? */
  1238.  
  1239.                                 if(LimitCount > 0)
  1240.                                     LimitCount--;
  1241.  
  1242.                                     /* Limit reached? */
  1243.  
  1244.                                 if(!LimitCount)
  1245.                                     Signal(ThisProcess,SIG_CHECK);
  1246.                             }
  1247.                         }
  1248.  
  1249.                             /* Make the colours blink. */
  1250.  
  1251.                         if(Screen && !Config -> ScreenConfig -> UseWorkbench)
  1252.                         {
  1253.                             if(Screen == IntuitionBase -> FirstScreen)
  1254.                             {
  1255.                                     /* No main screen window active? */
  1256.  
  1257.                                 if(StatusWindow)
  1258.                                 {
  1259.                                     if(!(Window -> Flags & WFLG_WINDOWACTIVE) && !(StatusWindow -> Flags & WFLG_WINDOWACTIVE))
  1260.                                         StandardColours = TRUE;
  1261.                                 }
  1262.                                 else
  1263.                                 {
  1264.                                     if(!(Window -> Flags & WFLG_WINDOWACTIVE))
  1265.                                         StandardColours = TRUE;
  1266.                                 }
  1267.  
  1268.                                     /* Menu button pressed or window disabled? */
  1269.  
  1270.                                 if(Window -> Flags & (WFLG_MENUSTATE | WFLG_INREQUEST))
  1271.                                     StandardColours = TRUE;
  1272.  
  1273.                                     /* User is currently dragging the
  1274.                                      * mouse in order to mark something
  1275.                                      * on the screen?
  1276.                                      */
  1277.  
  1278.                                 if(Marking)
  1279.                                     StandardColours = TRUE;
  1280.  
  1281.                                 Background = FALSE;
  1282.                             }
  1283.                             else
  1284.                             {
  1285.                                 if(!Background)
  1286.                                     StandardColours = TRUE;
  1287.  
  1288.                                 Background = TRUE;
  1289.                             }
  1290.  
  1291.                             if(StandardColours)
  1292.                             {
  1293.                                 if(!SetColours)
  1294.                                 {
  1295.                                     LoadColourTable(VPort,NormalColourTable,NormalColours,PaletteSize);
  1296.  
  1297.                                     SetColours = TRUE;
  1298.                                 }
  1299.  
  1300.                                 StandardColours = FlashIt = FALSE;
  1301.                             }
  1302.                             else
  1303.                             {
  1304.                                     /* Are we to flash the display? */
  1305.  
  1306.                                 if(Config -> ScreenConfig -> Blinking)
  1307.                                 {
  1308.                                     if(Screen == IntuitionBase -> FirstScreen)
  1309.                                     {
  1310.                                         if(FlashIt)
  1311.                                         {
  1312.                                             LoadColourTable(VPort,BlinkColourTable,BlinkColours,PaletteSize);
  1313.  
  1314.                                             SetColours = FALSE;
  1315.                                         }
  1316.                                         else
  1317.                                         {
  1318.                                             LoadColourTable(VPort,NormalColourTable,NormalColours,PaletteSize);
  1319.  
  1320.                                             SetColours = TRUE;
  1321.                                         }
  1322.                                     }
  1323.  
  1324.                                     FlashIt ^= TRUE;
  1325.                                 }
  1326.                             }
  1327.                         }
  1328.                     }
  1329.  
  1330.                     CloseDevice(StatusTimeRequest);
  1331.                 }
  1332.  
  1333.                 DeleteIORequest(StatusTimeRequest);
  1334.             }
  1335.  
  1336.             DeleteMsgPort(StatusTimePort);
  1337.         }
  1338.  
  1339.         if(StatusDisplayTask)
  1340.         {
  1341.             Forbid();
  1342.  
  1343.             Signal(StatusDisplayTask,SIG_KILL);
  1344.  
  1345.             ClrSignal(SIG_HANDSHAKE);
  1346.  
  1347.             Wait(SIG_HANDSHAKE);
  1348.  
  1349.             Permit();
  1350.         }
  1351.  
  1352.         if(BoxList)
  1353.             SZ_FreeBoxes(BoxList);
  1354.     }
  1355.  
  1356.     if(UpdateSig != -1)
  1357.         FreeSignal(UpdateSig);
  1358.  
  1359.         /* Signal the father process that we're done
  1360.          * and quietly remove ourselves.
  1361.          */
  1362.  
  1363.     Forbid();
  1364.  
  1365.     Signal(ThisProcess,SIG_HANDSHAKE);
  1366.  
  1367.     StatusProcess = NULL;
  1368. }
  1369.  
  1370.     /* ForceStatusUpdate():
  1371.      *
  1372.      *    Make sure that the status display gets updated
  1373.      *    as soon as possible.
  1374.      */
  1375.  
  1376. VOID
  1377. ForceStatusUpdate()
  1378. {
  1379.     if(StatusProcess && Window)
  1380.     {
  1381.             // Stop the execution
  1382.  
  1383.         Forbid();
  1384.  
  1385.         Signal(StatusProcess,UpdateMask);
  1386.  
  1387.         ClrSignal(SIG_HANDSHAKE);
  1388.  
  1389.         Wait(SIG_HANDSHAKE);
  1390.  
  1391.         Permit();
  1392.  
  1393.             // Ok, the status process is waiting, now update the data
  1394.  
  1395.         DropMarker();
  1396.  
  1397.         UpdateTerminalLimits();
  1398.  
  1399.             // Clear the window
  1400.  
  1401.         SetAPen(Window -> RPort,DrawInfo -> dri_Pens[BACKGROUNDPEN]);
  1402.         RectFill(Window -> RPort,Window -> BorderLeft,Window -> BorderTop,Window -> Width - (Window -> BorderLeft + Window -> BorderRight + 1),Window -> Height - (Window -> BorderTop + Window -> BorderBottom + 1));
  1403.  
  1404.             // Restart the status process
  1405.  
  1406.         Signal(StatusProcess,UpdateMask);
  1407.  
  1408.             // Repaint the window border, in case it got trashed
  1409.  
  1410.         RefreshWindowFrame(Window);
  1411.     }
  1412. }
  1413.